package com.calvin.study.multithread.thread;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import com.calvin.study.utils.Print;
import com.calvin.study.utils.ThreadUtil;

public class Thread08 {

	public static void main(String[] args) throws InterruptedException {
		T t = new T();
		Print.cfo(t.getName() + "\t 创建Thread实例，此时状态：" + t.getState());
		t.start();

		while (Thread.State.TERMINATED != t.getState()) {
			Print.cfo(t.getName() + "\t 状态：" + t.getState());
			Thread.sleep(500);
		}
		Print.cfo(t.getName() + "\t 线程结束， 状态：" + t.getState());
	}

}

class T extends Thread {
	
	@Override
	public void run() {
		while (true) {
			for (int i = 0, len = 10; i <= len; i++) {
				Print.cfo("hi" + i);
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
				}
			}
			break;
		}
	}
}

//线程状态实例
class StatusDemo {
	// 每个线程执行的轮次
	public static final long MAX_TURN = 5;
	// 线程编号
	static int threadSeqNum = 0;
	// 全局的静态线程列表
	static List<Thread> threadList = new ArrayList<>();

	private static void printThreadStatus() {
		//从线程列表中，获取每个线程当前状态
		for (Thread t : threadList) {
			System.out.println(t.getName() + " 状态为： " + t.getState());
		}
	}

	// 向全局的静态线程列表加入线程
	private static void addStatusThread(Thread thread) {
		threadList.add(thread);
	}

	static class StatusDemoThread extends Thread {
		public StatusDemoThread() {
			super("statusPrintThread" + (++threadSeqNum));
			// 将自己加入到全局的静态线程列表
			addStatusThread(this);
		}

		public void run() {
			System.out.println(getName() + ", 状态为" + getState());
			for (int turn = 0; turn < MAX_TURN; turn++) {
				// 线程睡眠
				ThreadUtil.sleepMilliSeconds(500);
				// 输出所有线程的状态
				printThreadStatus();
			}
			System.out.println(getName() + "- 运行结束.");
		}
	}

	public static void main(String args[]) throws InterruptedException {
		// 将main线程加入全局列表
		addStatusThread(Thread.currentThread());
		
		// 新建三个线程， 这些线程在构造器中会将自己加入全局列表
		Thread sThread1 = new StatusDemoThread();
		Print.cfo(sThread1.getName() + "- 状态为" + sThread1.getState());
		Thread sThread2 = new StatusDemoThread();
		Print.cfo(sThread2.getName() + "- 状态为" + sThread2.getState());
		Thread sThread3 = new StatusDemoThread();
		Print.cfo(sThread3.getName() + "- 状态为" + sThread3.getState());

		sThread1.start(); // 启动第一个线程
		ThreadUtil.sleepMilliSeconds(500); // 等待500毫秒启动第二个线程

		sThread2.start();
		ThreadUtil.sleepMilliSeconds(500); // 等待1000毫秒启动第三个线程

		sThread3.start();
		TimeUnit.SECONDS.sleep(100); // 睡眠100秒
	}
}

//线程的Sleep操作
class SleepDemo {

	public static final int SLEEP_GAP = 5000; // 睡眠时长5秒
	public static final int MAX_TURN = 5; // 睡眠次数， 稍微多点方便使用Jstack

	static class SleepThread extends Thread {
		static int threadSeqNumber = 1;

		public SleepThread() {
			super("sleepThread-" + threadSeqNumber);
			threadSeqNumber++;
		}

		public void run() {
			try {
				for (int i = 1; i < MAX_TURN; i++) {
					System.out.println(getName() + ", 睡眠轮次： " + i);
					// 线程睡眠一会
					Thread.sleep(SLEEP_GAP);
				}
			} catch (InterruptedException e) {
				System.out.println(getName() + " 发生异常被中断.");
			}
			System.out.println(getName() + " 运行结束.");
		}
	}

	public static void main(String args[]) throws InterruptedException {
//		for (int i = 0; i < 5; i++) {
//			Thread thread = new SleepThread();
//			thread.start();
//		}
		Thread thread1 = new SleepThread();
		thread1.start();
		Thread thread2 = new SleepThread();
		thread2.start();

		ThreadUtil.sleepSeconds(2); // 主线程等待2秒
		thread1.interrupt(); //在第3秒时，主线程唤醒，中断线程1

		ThreadUtil.sleepSeconds(5); // 主线程等待5秒
		thread2.interrupt(); // 打断线程2， 此时线程2已经终止

		ThreadUtil.sleepSeconds(1); // 主线程等待1秒

		System.out.println(ThreadUtil.getCurThreadName() + " 运行结束.");
	}
}

//线程合并操作
class JoinDemo{
	public static final int SLEEP_GAP = 5000;//睡眠时长
	public static final int MAX_TURN = 50;
	
	static class HotWaterThread extends Thread {
		public HotWaterThread() {
			super("** 烧水-Thread");
		}

		public void run() {
			try {
				Print.tcfo("洗好水壶");
				Print.tcfo("灌上凉水");
				Print.tcfo("放在火上");
				// 线程睡眠一段时间，代表烧水中
				Thread.sleep(1000);
				Print.tcfo("水开了");

			} catch (InterruptedException e) {
				Print.tcfo(" 发生异常被中断.");
			}
			Print.tcfo(" 运行结束.");
		}
	}
	
    static class WashThread extends Thread {
        public WashThread() {
            super("$$ 清洗-Thread");
        }

        public void run() {

            try {
                Print.tcfo("洗茶壶");
                Print.tcfo("洗茶杯");
                Print.tcfo("拿茶叶");
                //线程睡眠一段时间，代表清洗中
                Thread.sleep(500);
                Print.tcfo("洗完了");

            } catch (InterruptedException e) {
                Print.tcfo(" 发生异常被中断.");
            }
            Print.tcfo(" 运行结束.");
        }
    }
    
    public static void main(String args[]) {

        Thread hThread = new HotWaterThread();
        Thread wThread = new WashThread();

        hThread.start();
        wThread.start();
        try {
            // 合并烧水-线程
            hThread.join();
            // 合并清洗-线程
            wThread.join();

            Thread.currentThread().setName("主线程");
            Print.tcfo("泡茶喝");

        } catch (InterruptedException e) {
            Print.tcfo(ThreadUtil.getCurThreadName() + "发生异常被中断.");
        }
        Print.tcfo(ThreadUtil.getCurThreadName() + " 运行结束.");
    }
	
	
}


//线程让步操作
class YieldDemo {

	public static final int MAX_TURN = 100; // 执行次数
	public static AtomicInteger index = new AtomicInteger(0); // 执行编号
	// 记录线程的执行次数
	private static Map<String, AtomicInteger> metric = new HashMap<>();

	// 输出线程的执行次数
	private static void printMetric() {
		System.out.println("metric = " + metric);
	}

	static class YieldThread extends Thread {
		static int threadSeqNumber = 1;

		public YieldThread() {
			super("sleepThread-" + threadSeqNumber);
			threadSeqNumber++;
			// 将线程加入到执行次数统计map
			metric.put(this.getName(), new AtomicInteger(0));
		}

		public void run() {
			for (int i = 1; i < MAX_TURN && index.get() < MAX_TURN; i++) {
				System.out.println(ThreadUtil.getCurThreadName() + " 线程优先级： " + getPriority());
				index.incrementAndGet();
				//对线程执行次数累加（统计一次）
				metric.get(this.getName()).incrementAndGet();
				//每执行两次让出CPU，CPU根据线程优先级高的继续执行。
				if (i % 2 == 0) {
					System.out.println(i);
					// 让步： 出让执行的权限
					Thread.yield();
				}
			}
			// 输出所有线程的执行次数
			printMetric();
			System.out.println(getName() + " 运行结束.");
		}
	}

	public static void main(String[] args) throws InterruptedException {
		// 设置为最高的优先级
		Thread thread1 = new YieldThread();
		thread1.setPriority(Thread.MAX_PRIORITY);

		// 设置为最低的优先级
		Thread thread2 = new YieldThread();
		thread2.setPriority(Thread.MIN_PRIORITY);

		System.out.println("启动线程.");
		thread1.start();
		thread2.start();

		ThreadUtil.sleepSeconds(100);
	}
}

//守护线程操作
class DeamonDemo {
	public static final int SLEEP_GAP = 3000; // 每一轮的睡眠时长
	public static final int MAX_TURN = 4; // 用户线程执行轮次

	static class DeamonThread extends Thread {
		public DeamonThread() {
			super("deamonThread-");
		}

		@Override
		public void run() {
			System.out.println("--daemon线程开始.");
			for (int i = 1;; i++) // 死循环
			{
				System.out.println("--daemon轮次： " + i);
				System.out.println("--daemon守护状态为:" + isDaemon());
				// 线程睡眠一会儿， 500毫秒
				ThreadUtil.sleepMilliSeconds(SLEEP_GAP);
			}
		}
	}

	public static void main(String[] args) {
		Thread deamonThread = new DeamonThread();
		deamonThread.setDaemon(true);// 设为守护线程
		deamonThread.start();

		// 创建一个用户线程， 执行4轮
		Thread userThread = new Thread(() -> {
			System.out.println(">>userThread用户线程开始.");
			for (int i = 1; i <= MAX_TURN; i++) {
				System.out.println(">>userThread轮次： " + i);
				System.out.println(">>userThread守护状态为:" + ThreadUtil.getCurThread().isDaemon());
				ThreadUtil.sleepMilliSeconds(SLEEP_GAP);
			}
			System.out.println(">>userThread用户线程结束.");
		}, "userThread");
		// 启动用户线程
		userThread.start();
		
		System.out.println(" 守护状态为:" + ThreadUtil.getCurThread().isDaemon());
		System.out.println(" 运行结束.");

	}
}
